package com.jahentao.patentQuery.web.controller;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.jahentao.patentQuery.constant.EhCacheKeys;
import com.jahentao.patentQuery.constant.SysUri;
import com.jahentao.patentQuery.exception.TaskException;
import com.jahentao.patentQuery.model.*;
import com.jahentao.patentQuery.model.bean.MessageCode;
import com.jahentao.patentQuery.model.bean.ResultBean;
import com.jahentao.patentQuery.model.page.QueryResult;
import com.jahentao.patentQuery.model.progress.AbstractTask;
import com.jahentao.patentQuery.model.progress.Progress;
import com.jahentao.patentQuery.service.PatentDemandQueryService;
import com.jahentao.patentQuery.service.PatentDemandService;
import com.jahentao.patentQuery.service.PatentSupplyQueryService;
import com.jahentao.patentQuery.web.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @author jahentao
 * @date 2018/5/1
 * @since 1.0
 */
@Controller
@RequestMapping(SysUri.SUPPLY_QUERY)
public class PatentSupplyQueryController extends BaseController {
    @Autowired
    private PatentSupplyQueryService patentSupplyQueryService;
    @Resource
    private CacheManager springCacheManager;
    @Autowired
    private PatentDemandService patentDemandService;

    /**
     * 任务编号。
     * <p>有个缺点，重启应用之后，该编号又要从1开始</p>
     * <p>也罢，就限定任务在重启之后，全部失效</p>
     */
    static final AtomicLong TASK_ID_NUMBER = new AtomicLong(1);

    // =============================页面跳转===================================

    @RequestMapping(value = "list")
    public String list() {
        return "admin/supplyQuery/list";
    }

    // =============================流程控制===================================

    @ResponseBody
    @RequestMapping(value = "getList",method = RequestMethod.POST)
    public ResultBean getList(@RequestParam(value = "pageNumber", defaultValue = "1")Integer pageNumber,
                              @RequestParam(value = "pageSize", defaultValue = "10")Integer pageSize) {
        ResultBean rb = new ResultBean();

        PatentSupplyQueryExample patentSupplyQueryExample = new PatentSupplyQueryExample();
        patentSupplyQueryExample.setOrderByClause("query_time desc");

        // 分页查询
        PageHelper.startPage(pageNumber, pageSize);
        List<PatentSupplyQuery> patentDemandQueries = patentSupplyQueryService.selectByExample(patentSupplyQueryExample);

        Page patentDemandQueriesPage = (Page) patentDemandQueries;
        QueryResult<PatentSupplyQuery> queryResult = new QueryResult<PatentSupplyQuery>();
        queryResult.setCurrentPage(pageNumber);
        queryResult.setShowNum(pageSize);
        queryResult.setPages(patentDemandQueriesPage.getTotal(), pageSize);
        queryResult.setItems(patentDemandQueries);

        // 返回结果
        rb.setData(queryResult);

        return rb;
    }


    @ResponseBody
    @RequestMapping(value = "deleteIds", method = RequestMethod.POST)
    public ResultBean deleteIds(@RequestParam(value = "ids[]") Long[] ids) {
        ResultBean rb = new ResultBean();

        boolean allSuccess = true;

        for (Long id : ids) {
            final int deleted = patentSupplyQueryService.delete(id);
            allSuccess &= deleted > 0;
        }

        if (allSuccess) {
            rb.setMessageCode(MessageCode.SUCCESS);
            rb.setMessage("都删除成功");
        }else {
            rb.setMessageCode(MessageCode.DELETE_FAILURE);
            rb.setMessage("删除失败，或部分删除成功");
        }

        return rb;
    }

    /**
     * 将专利搜索记录转换导入需求管理表中
     * <p>注意时间筛选[start,end]，为方便用户理解和操作，左闭右闭，
     * 但因为内部类访问必须不能修改，end+1天的任务交给前端，后端处理时，仍是[start,end)，左闭右开/p>
     * @param start
     * @param end
     * @param selectAll
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "convert", method = RequestMethod.POST)
    public ResultBean convert(@RequestParam(value = "start") Date start,
                              @RequestParam(value = "end") Date end,
                              @RequestParam(value = "selectAll", defaultValue = "false")Boolean selectAll) {
        logger.debug("批量转换，是否全部转换：" + Boolean.valueOf(selectAll));
        if (!selectAll) {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            logger.debug("转换时间选择：" + formatter.format(start) + " - " + formatter.format(end));
        }

        ResultBean rb = new ResultBean();
        Map<String, Object> data = new HashMap<String, Object>(1);
        Cache cache = springCacheManager.getCache(EhCacheKeys.ASYNC_SUPPLY_QUERY_IMPORT_TO_DEMAND_TASK_CACHE);

        data.put("taskId", TASK_ID_NUMBER.get());
        try {
            patentSupplyQueryService.asyncTask(new AbstractTask(TASK_ID_NUMBER.getAndIncrement()) {
                @Override
                public void execute() {
                    PatentSupplyQueryExample patentSupplyQueryExample = new PatentSupplyQueryExample();
                    if (!selectAll) {
                        patentSupplyQueryExample.createCriteria().andQueryTimeBetween(start, end);
                    }
                    // TODO 如果数据量很大，为优化性能，以后可以改为100条的循环查询，再操作
                    List<PatentSupplyQuery> patentSupplyQueries = patentSupplyQueryService.selectByExample(patentSupplyQueryExample);
                    Progress progress = this.getProgress();
                    progress.setTotal(patentSupplyQueries.size());
                    progress.setCompleted(0);
                    progress.setPercentage(0F);

                    long patentDemandConflictNumber = 0L;
                    long success = 0L;

                    for (PatentSupplyQuery query : patentSupplyQueries) {
                        // {content, id, query_time}作为三元组是否存在
                        PatentDemandExample example = new PatentDemandExample();
                        example.createCriteria().andContentEqualTo(query.getKey())
                                                .andUserIdEqualTo(query.getUser().getId())
                                                .andDemandTimeEqualTo(query.getQueryTime());
                        List<PatentDemand> patentDemands = patentDemandService.selectByExample(example);
                        if (patentDemands == null || patentDemands.size() == 0) {
                            // 搜索记录 不存在，插入
                            PatentDemand patentDemand = new PatentDemand();
                            patentDemand.setContent(query.getKey());
                            patentDemand.setDemandTime(query.getQueryTime());
                            patentDemand.setUser(query.getUser());
                            patentDemandService.save(patentDemand);
                        } else {
                            ++ patentDemandConflictNumber;
                        }

                        ++ success;

                        // 更新cache
                        progress.setCompleted(progress.getCompleted() + 1);
                        logger.debug("task {} 目前进度：{}", getId(), progress.getPercentage());
                        cache.put(this.getId(), progress.getPercentage());
                    }
                }
            });
        } catch (TaskException e) {
            e.printStackTrace();
        }
        rb.setData(data);
        return rb;
    }

    @ResponseBody
    @RequestMapping(value = "getProgress", method = RequestMethod.POST)
    public ResultBean getProgress(Long taskId) {
        ResultBean rb = new ResultBean();
        Map<String, Object> data = new HashMap<String, Object>(2);
        String process = patentSupplyQueryService.getProcess(taskId);
        // 将清理缓存的任务交给查看进度
        if (process.startsWith(Progress.COMPLETE_PERCENTAGE)) {
            patentSupplyQueryService.clearCache(taskId);
        }
        data.put("taskId", taskId);
        data.put("progress", process);
        rb.setData(data);
        return rb;
    }
}
